// 基础类型
(() => {
  // console.log('测试')
  // 布尔类型 -----> boolean
  // let 变量名：数据类型 = 值
  let flag: boolean = true

  // 数字类型 -----> number
  let a1: number = 10 // 十进制
  let a2: number = 0b1010 // 二进制
  let a3: number = 0o12 // 八进制
  let a4: number = 0xa // 十六进制

  // 字符串类型 -----> string
  let name: string = 'tom'
  name = 'jack'
  // name = 12 // error
  let age: number = 12
  const info = `My name is ${name}, I am ${age} years old!`

  // 总结 ts中变量一开始是什么类型那么后续赋值的时候，只能用这个类型的数据，是不允许使用其他数据类型赋值给当前变量

  // undefined、null  
  // TypeScript 里，undefined 和 null 两者各自有自己的类型分别叫做 undefined 和 null。 它们的本身的类型用处不是很大：
  let u: undefined = undefined
  let n: null = null
  // 默认情况下 null 和 undefined 是所有类型的子类型。
  //  就是说你可以把 null 和 undefined 赋值给 number 类型的变量。
  let a5: number = null
  // 需要在tsconfig.json中关闭严格模式

  // 可以直接使用字面量进行类型声明
  let a: 10
  a = 10
  // a = 11 //报错a只能为10
  // 可以使用  |  来连接多个类型（联合类型）
  let b: 'man' | 'women'
  b = 'man'
  b = 'women'

  let c: boolean | string
  c = true
  c = 'hello'

  // any 表示是任意类型，一个变量设置any后相当于对该变量关闭了TS的类型检测
  // 使用TS时，不建议使用any类型
  // let d  //声明变量如果不指定类型，则TS解析器会自动判断变量类型为any（隐式的any）
  let d: any //显示的any
  d = 10
  d = true
  d = 'hello'

  // unknown 表示未知类型的值
  let e: unknown
  e = 10
  e = true
  e = 'hello'

  let f: string
  // d的类型是any，它可以赋值给任意变量
  f = d

  e = 'hello'
  // unknown 实际上就是一个类型安全的any
  // unknown类型的变量，不能赋值给其他变量
  // f = e  错误
  if (typeof e === 'string') {
    f = e
  }

  // 类型断言 可以用来告诉解析器变量的实际类型
  /**
   * 语法：
   * 变量 as 类型
   * 或者
   * <类型>变量
   */
  f = e as string
  f = <string>e

  // void用来表示空，以函数为例，就表示没有返回值的函数
  function fn(): void {
  }

  // never表示永远不会返回结果
  function fn2(): never {
    throw new Error('报错了')
  }

})()
